LIBRARY IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.control_sm;
USE WORK.controller;
USE WORK.tester; 
USE WORK.filter;
USE WORK.decider;

--Testador Completo

ENTITY box IS
    PORT(clock, start_test: IN STD_LOGIC := '0';
        l_pin: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1);
        r_pin: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1);
		  works: OUT STD_LOGIC := '0';
		  LCD: OUT STD_LOGIC_VECTOR(12 DOWNTO 0));
END box;

ARCHITECTURE logic OF box IS

COMPONENT control_sm
    PORT(clock, start_test: IN STD_LOGIC := '0';
        ic_found: IN STD_LOGIC_VECTOR(1 DOWNTO 0) := "10";
        ic: IN STD_LOGIC_VECTOR(11 DOWNTO 0) := "000000000000";
        reset: OUT STD_LOGIC := '1';
        filter_enable: OUT STD_LOGIC := '0';
        address: OUT STD_LOGIC_VECTOR(9 DOWNTO 0) := "0000000000";
        LCD_address: OUT STD_LOGIC_VECTOR(9 DOWNTO 0) := "0000000000";
        test_state: OUT STD_LOGIC_VECTOR(4 DOWNTO 0) := "00000";
        result: OUT STD_LOGIC := '0');
END COMPONENT;

COMPONENT controller IS
    PORT(test_addr: IN STD_LOGIC_VECTOR (9 DOWNTO 0) := "0000000000";
        LCD_addr: IN STD_LOGIC_VECTOR (9 DOWNTO 0) := "0000000000";
        test_state: IN STD_LOGIC_VECTOR(4 DOWNTO 0) := "00000"; 
        l_pin: OUT STD_LOGIC_VECTOR (7 DOWNTO 1) := (OTHERS => 'Z');
		  r_pin: OUT STD_LOGIC_VECTOR (7 DOWNTO 1) := (OTHERS => 'Z');
        LCD: OUT STD_LOGIC_VECTOR(12 DOWNTO 0));
END COMPONENT;

COMPONENT tester
    PORT(clock, reset: IN STD_LOGIC := '0';
        r_pin: IN STD_LOGIC_VECTOR(7 DOWNTO 1);
        l_pin: IN STD_LOGIC_VECTOR(7 DOWNTO 1);
        works: OUT STD_LOGIC := '1';
        ic: OUT STD_LOGIC_VECTOR(11 DOWNTO 0):= (OTHERS => '0'));
END COMPONENT;

COMPONENT decider
    PORT(ic: IN STD_LOGIC_VECTOR(11 DOWNTO 0);
		  ic_found: OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END COMPONENT;

COMPONENT filter
    PORT(test_state: IN STD_LOGIC_VECTOR(4 DOWNTO 0) := "00000";
        filter_enable: IN STD_LOGIC := '0';
        l_in: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1);
        r_in: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1);
	     l_out: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1);
        r_out: INOUT STD_LOGIC_VECTOR(7 DOWNTO 1));
END COMPONENT;

COMPONENT show_ic
    PORT(ic: IN STD_LOGIC_VECTOR(11 DOWNTO 0);
        ic_found: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
		  result: IN STD_LOGIC;
        ic_id: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;

SIGNAL s_reset: STD_LOGIC := '1';
SIGNAL s_result: STD_LOGIC := '0';
SIGNAL fe_reg: STD_LOGIC := '0';
SIGNAL address: STD_LOGIC_VECTOR (9 DOWNTO 0) := "0000000000";
SIGNAL lcd_address: STD_LOGIC_VECTOR (9 DOWNTO 0) := "0000000000";
SIGNAL test_state_reg: STD_LOGIC_VECTOR(4 DOWNTO 0) := "00000";
SIGNAL l_reg: STD_LOGIC_VECTOR(7 DOWNTO 1) := (OTHERS => '0'); --sinais internos
SIGNAL r_reg: STD_LOGIC_VECTOR(7 DOWNTO 1) := (OTHERS => '0'); --sinais internos
SIGNAL s_ic: STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL s_ic_found: STD_LOGIC_VECTOR(1 DOWNTO 0) := "00";

BEGIN	 
    maquinadeestado: control_sm
    PORT MAP(clock=>clock, start_test=>start_test, ic_found=>s_ic_found, ic=>s_ic, reset=>s_reset, 
        filter_enable=>fe_reg, address=>address, lcd_address=>lcd_address,
        test_state=>test_state_reg, result=>s_result);
		 
    decisor : decider
    PORT MAP(ic=>s_ic, ic_found=>s_ic_found);

    testador: tester
    PORT MAP(clock=>clock, reset=>s_reset,
        l_pin(7 DOWNTO 1)=>l_reg(7 DOWNTO 1), r_pin(7 DOWNTO 1)=>r_reg(7 DOWNTO 1), works=>works, ic=>s_ic);

    controlador: controller
    PORT MAP(test_addr=>address, lcd_addr=>lcd_address, test_state=>test_state_reg, l_pin(7 DOWNTO 1)=>l_reg(7 DOWNTO 1),
        r_pin(7 DOWNTO 1)=>r_reg(7 DOWNTO 1), LCD(12 DOWNTO 0)=>LCD(12 DOWNTO 0));
	
    filtro: filter
    PORT MAP(test_state=>test_state_reg, filter_enable=>fe_reg,
        l_in(7 DOWNTO 1)=>l_reg(7 DOWNTO 1), r_in(7 DOWNTO 1)=>r_reg(7 DOWNTO 1), 
        l_out(7 DOWNTO 1)=>l_pin(7 DOWNTO 1), r_out(7 DOWNTO 1)=>r_pin(7 DOWNTO 1));
END logic;